package com.qjc.demo.thread.CyclicBarrier;

import java.util.concurrent.*;

/**
 * @Description: 回环屏障
 * @Author: qjc
 * @Date: 2020/7/27
 */
public class CyclicBarrierTest2 {

    /**
     * 假设一个任务由阶段1、阶段2和阶段3组成，每个线程要串行地执行阶段1、阶段2和阶段3，当多个线程执行该任务时，必须要保证所有线程的阶段1全部完成后才
     * 能进入阶段2执行， 当所有线程的阶段2全部完成后才能进入阶段3执行。下面使用CyclicBarrier 成这个需求
     */
    private static CyclicBarrier cyclicBarrier = new CyclicBarrier(2);

    private final static int THREAD_POOL_SIZE = 2;
    private final static long KEEP_ALIVE_TIME = 0L;


    public static void main(String[] args) {
//        ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
        ExecutorService executorService = new ThreadPoolExecutor(THREAD_POOL_SIZE, THREAD_POOL_SIZE, KEEP_ALIVE_TIME,
                TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(10), new ThreadPoolExecutor.AbortPolicy());
        executorService.submit(()->{
            try {
                System.out.println(Thread.currentThread()+" step1");
                cyclicBarrier.await();

                System.out.println(Thread.currentThread()+" step2");
                cyclicBarrier.await();

                System.out.println(Thread.currentThread()+" step3");
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        executorService.submit(()->{
            try {
                System.out.println(Thread.currentThread()+" step1");
                cyclicBarrier.await();

                System.out.println(Thread.currentThread()+" step2");
                cyclicBarrier.await();

                System.out.println(Thread.currentThread()+" step3");
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        executorService.shutdown();
    }

    /**
     * 每个子线程在执行完阶段1后都调用了 await 方法 等到所有线程都到达屏障点后才会一块往下执行，这就保证了所有线程都完成了阶段1后才会开始执行阶段2。
     * 然后在阶段2后面调用了 await 方法，这保证了所有线程都完成了阶段2后，才能开始阶段3的执行。这个功能使用单个CountDownLatch 是无法完成的。
     */

}
